package fechas;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Se encarga de trabajar con fechas. Convierte de String a Date, calcula cual
 * fue primero y la diferencia entre ellas.
 * 
 * @author grupo 2
 * 
 */
public class FechaUtils {

	// EXPRESIONES REGULARES PARA LA VALIDACION DE LAS FECHAS
	private static final String regexLatino = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";
	private static final String regexAmericano = "(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])-((19|20)\\d\\d)";
	private static final String regexIso8601 = "((19|20)\\d\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])";

	/**
	 * Convierte el string que representa una fecha, del formato Latino al tipo
	 * Date. En caso de error notifica a la consola y devuelve null
	 * 
	 * @param String
	 *            fecha
	 * @return Date
	 */

	public static Date stringToDateLatino(String fecha) {
		// valido que ingrese una fecha correspondiente a patron;
		if (fecha == null || !fecha.matches(regexLatino)) {
			System.err.println(fecha+" es una fecha invalida debe ingresar del tipo dd/MM/yyyy");
			return null;
		} else {
			DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
			try {
				return formatter.parse(fecha);
			} catch (ParseException e) {
				System.err.println("Error de Parseo");
			}

		}
		return null;

	}

	/**
	 * Convierte el string que representa una fecha, del formato Americano al
	 * tipo Date. En caso de error notifica a la consola y devuelve null
	 * 
	 * @param String
	 *            fecha
	 * @return Date
	 */
	public static Date stringToDateAmericano(String fecha) {
		// valido que ingrese una fecha correspondiente a patron;
		if (fecha == null || !fecha.matches(regexAmericano)) {
			System.err.println(fecha+" es una fecha invalida debe ingresar del tipo MM-dd-yyyy");
			return null;
		} else {
			DateFormat formatter = new SimpleDateFormat("MM-dd-yyyy");
			try {
				return formatter.parse(fecha);
			} catch (ParseException e) {
				System.err.println("Error de Parseo");

			}

		}
		return null;

	}

	/**
	 * Convierte el string que representa una fecha, del formato ISO al tipo
	 * Date. En caso de error notifica a la consola y devuelve null
	 * 
	 * @param String
	 *            fecha
	 * @return Date
	 */
	public static Date stringToDateIso8606(String fecha) {
		// valido que ingrese una fecha correspondiente a patron;
		if (fecha == null || !fecha.matches(regexIso8601)) {
			System.err.println(fecha+" es una fecha invalida debe ingresar del tipo yyyy-MM-dd");
			return null;
		} else {
			DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
			try {
				return formatter.parse(fecha);
			} catch (ParseException e) {
				System.err.println("Error de Parseo");

			}

		}
		return null;

	}

	/**
	 * Convierte el string que representa una fecha, de un formato desconocido
	 * al tipo Date. En caso de error notifica a la consola y devuelve null
	 * 
	 * @param String
	 *            fecha
	 * @return Date
	 */
	public static Date stringToDateFlexible(String fecha) {
		if (fecha != null) {
			if (fecha.matches(regexLatino))
				return stringToDateLatino(fecha);
			else if (fecha.matches(regexAmericano))
				return stringToDateAmericano(fecha);
			else if (fecha.matches(regexIso8601))
				return stringToDateIso8606(fecha);
		}
		System.err.println(fecha+" Formato de Fecha No Soportado");
		return null;
	}

	/**
	 * Calcula la diferencia en dias entre dos fechas ingresadas como String en
	 * un formato compatible en caso de Error devuelve -1
	 * 
	 * @param fechaUno
	 *            String
	 * @param fechaDos
	 *            String
	 * @return Diferencia
	 */
	public static long diferenciaEntreFechasEnDias(String fechaUno,
			String fechaDos) {

		Date primerFecha = FechaUtils.stringToDateFlexible(fechaUno);
		Date segundaFecha = FechaUtils.stringToDateFlexible(fechaDos);
		if(primerFecha!=null && segundaFecha!=null){
			long diferencia = (Math.abs(primerFecha.getTime()
					- segundaFecha.getTime()) / 86400000);
			System.out.println("La diferencia de dias entre "+ fechaUno+ " y "+ fechaDos+" es "+ diferencia);
			return diferencia;
		}
		else{
			System.err.println("Hubo un error");
			return -1;
		}

	}

	/**
	 * 
	 * Devuelve 1 si la primera fecha es anterior a la segunda 
	 * 0 si es falso
	 * -1 si hay error
	 * 
	 * @param fechaUno
	 *            String
	 * @param fechaDos
	 *            String
	 * @return Bool
	 */
	public static long esFechaAnterior(String fechaUno, String fechaDos) {
		Date primerFecha = null, segundaFecha = null;

		primerFecha = FechaUtils.stringToDateFlexible(fechaUno);
		segundaFecha = FechaUtils.stringToDateFlexible(fechaDos);

		if(primerFecha!=null && segundaFecha!=null){
			if (primerFecha.getTime() < segundaFecha.getTime()) {
				System.out.println("Es verdadero");
				return 1;
			} else {
				System.out.println("Es falso");
				return 0;
			}
			
		}
		System.err.println("Hubo un error");
		return -1;

	}
}
